package com.imagination.applet.controller.api.callback;

import com.alibaba.fastjson.JSONObject;
import com.imagination.applet.domain.revenue.order.service.OrderService;
import com.wechat.pay.java.core.RSAConfig;
import com.wechat.pay.java.core.cipher.PrivacyDecryptor;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.util.GsonUtil;
//import io.swagger.v3.oas.annotations.Operation;
//import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping(value = "/wechat/callback")
//@Tag(name = "微信回调服务")
@Slf4j
public class WechatCallbackController {

    @Value("${payment.wechat.app-id}")
    private String appId;
    @Value("${payment.wechat.merchant-id}")
    private String merchantId;
    /**
     * 商户证书序列号
     */
    @Value("${payment.wechat.merchant-serial-number}")
    public String merchantSerialNumber;
    /**
     * 商户API私钥路径
     */
    @Value("${payment.wechat.private-key-path}")
    public String privateKeyPath;
    /**
     * 商户API证书
     */
    @Value("${payment.wechat.cert-path}")
    public String certPath;
    /**
     * 商户APIV3密钥
     */
    @Value("${payment.wechat.api-v3-key}")
    public String apiV3Key;
    @Autowired
    private OrderService orderService;

    @PostMapping(value = "/pay.do")
//    @Operation(summary = "支付回调（待实现）")
    public Map<String, Object> pay(@RequestBody JSONObject param) throws Exception {
        log.info("支付回调 {}", param.toJSONString());
        String key = apiV3Key;
        JSONObject resourceMap = param.getJSONObject("resource");
        String associated_data = resourceMap.getString("associated_data");
        //得到我的这个随机串
        byte[] nonce = resourceMap.getString("nonce").getBytes(StandardCharsets.UTF_8);
        //得到这个密文数据
        String ciphertext = resourceMap.getString("ciphertext");
        // 解密
        String decryptData = new AesUtil(key.getBytes(StandardCharsets.UTF_8)).decryptToString(associated_data.getBytes(StandardCharsets.UTF_8), nonce, ciphertext);
        //验签成功
        JSONObject resData = JSONObject.parseObject(decryptData, JSONObject.class);
        log.info("回调解析:{}", resData.toJSONString());
        // 回调微信
        Map<String, Object> res = new HashMap<>();
        if ("SUCCESS".equals(resData.getString("trade_state"))) {
            orderService.wxCallBackOrder(resData.getString("out_trade_no"), resData);
            res.put("code", "SUCCESS");
            res.put("message", "成功");
            return res;
        }
        res.put("code", "ERROR");
        res.put("message", "通知验签失败");
        return res;
    }

    /**
     * 对称解密
     */
    private static String decryptFromResource(Map<String, Object> bodyMap, String key) {
        // 通知数据
        Map<String, String> resourceMap = (Map) bodyMap.get("resource");
        // 数据密文
        String ciphertext = resourceMap.get("ciphertext");
        // 随机串
        String nonce = resourceMap.get("nonce");
        // 附加数据
        String associateData = resourceMap.get("associated_data");
        AesUtil aesUtil = new AesUtil(key.getBytes(StandardCharsets.UTF_8));
        try {
            return aesUtil.decryptToString(associateData.getBytes(StandardCharsets.UTF_8), nonce.getBytes(StandardCharsets.UTF_8), ciphertext);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("解密失败");
        }
    }
}
